# -*- coding: utf-8 -*-
import requests
from requests.utils import dict_from_cookiejar, add_dict_to_cookiejar, cookiejar_from_dict

"""
1.设置代理
(1）全局代理
    session = requests.Session()
    session.proxies = {'http': 'http://127.0.0.1:8080'}
    session.verify = False  # verify是否验证服务器ssl证书
    session.get(url='')
(2)每次请求设置代理
    proxies = {'http': 'http://127.0.0.1:8080'}
    session.get(url='', proxies=proxies, verify=False)

2.请求参数
    url：就是要请求的url，例如https://jiajunhuang.com，是必填的。
    params：是query string，可以是一个字典，或者一个list，list的内容是一堆的tuple，也可以是bytes。
    data： 是HTTP请求中的body，可以是一个字典，或者一个list，list的内容是一堆的tuple，也可以是bytes或者文件
    json： 将对象转为json字符串作为HTTP请求中的body，会自动把请求的Content-Type设置为application/json
    headers：是HTTP请求中的头部，是一个字典，如{'User-Agent':'...'}
    cookies： 是所携带的Cookie，可以是一个字典或者CookieJar的实例
    files： 是要上传的文件，可以是一个字典，字典的内容是tuple
    auth：用于开启HTTP请求的认证
    timeout：超时时间，单位是秒，float类型
    allow_redirects：是否允许重定向，是一个布尔值
    proxies：是否使用代理
    verify：是否检查服务端的证书，传布尔值或者CA的路径
    stream：是布尔值，代表是否以流的方式读取结果
    cert：传入客户端的SSL证书

3.文件上传
(1)官方推荐使用的字典参数格式如下：
    { "field0" : open("filePath1", "rb"),
      "field1" : ("filename1", open("filePath1", "rb")),
      "field2" : ("filename2", open("filePath2", "rb"), "image/jpeg"),
      "field3" : ("filename3", open("filePath3", "rb"), "image/jpeg", {"refer" : "localhost"}) } 
    key是post请求的字段名，而value是("filename", "fileobject", "content-type", "headers")
(2)元组列表类型的files参数
    [ ("field0" : open("filePath1", "rb")),
      ("field1" : ("filename1", open("filePath1", "rb"))),
      ("field2" : ("filename2", open("filePath2", "rb"), "image/jpeg")),
      ("field3" : ("filename3", open("filePath3", "rb"), "image/jpeg", {"refer" : "localhost"}))]
"""

"""发送json数据"""
js = {'a': 1, 'b': 2}
# requests.post(url='https://www.baidu.com', json=js, verify=False)

"""单文件上传"""
files_1 = {'text': open('a.txt', 'rb')}  # 最简单的文件上传，文件名默认为上传文件的名称
files_2 = {'text': ('b.txt', open('a.txt', 'rb'), 'text/plain')}  # 显式地设置文件名，文件类型
files_3 = {'text': ('中文.txt', '中文')}  # 直接发送字符串作为文件内容

"""多文件上传"""
# （1）多字段上传多个文件，即一个表单有多个文件上传控件
files_4 = {'text1': ('a.txt', open('a.txt', 'rb')), 'text2': ('b.txt', open('a.txt', 'rb'))}
# （2）单字段上传多个文件，即上传文件时设置为多选了
files_5 = [('texts', ('a.txt', open('a.txt', 'rb'), 'text/plain')),
           ('texts', ('b.txt', open('a.txt', 'rb'), 'text/plain'))]
# response = requests.post(url='', files=files_4, verify=False)

"""返回数据中文乱码问题"""
# res = requests.get(url='https://www.baidu.com')
# res.encoding = res.apparent_encoding
# 或者res.encoding = None
# 或者res.content.decode('正确编码格式')
# print(res.encoding, res.text)

"""提交数组参数"""
params = {'a[]': [1, 2, 3]}
params2 = [('a[]', 1), ('a[]', 2), ('a[]', 3)]
# res = requests.get(url='http://106.52.133.241:81/a.php', params=params2, verify=False)

"""常规下载"""
def download(url, filepath):
    response = requests.get(url)
    with open(filepath, 'wb') as fp:
        fp.write(response.content)
    print('下载完成')

"""大文件下载"""
def download_steam(url, filepath):
    with requests.get(url, stream=True) as r:
        # print(r.headers)
        file_size = int(r.headers['content-length'])  # 文件大小,单位是字节bytes
        down_size = 0  # 当前下载大小
        with open(filepath, 'wb') as f:
            for chunk in r.iter_content(8192):
                f.write(chunk)
                down_size += len(chunk)
                print('\r下载进度：{:.2%}'.format(down_size/file_size), end='', flush=True)  # 原地刷新方式输出
    print('下载完成')

"""全局header和cookie"""
s = requests.Session()
# header
s.headers['User-Agent'] = 'qwdwdw'
s.headers = {'User-Agent': 'qwdwdw'}
# cookie
s.cookies['a'] = '1'  # 方式1
s.cookies.set('a', '1', path='/', domain='www.baidu.com')  # 方式2
cookie = {'a': '1'}
s.cookies = cookiejar_from_dict(cookie)  # 方式3
add_dict_to_cookiejar(s.cookies, cookie)  # 方式4
# cookiejar转dict
dict_from_cookiejar(s.cookies)